package com.xingda.packing.dmss.domain;

import com.xingda.packing.dmss.common.StorageUtils;
import com.xingda.packing.dmss.enums.*;
import com.xingda.packing.dmss.events.EventCreater;
import com.xingda.packing.dmss.minitor.entity.PkVisualSense;
import com.xingda.packing.dmss.minitor.mapper.PkVisualSenseMapper;
import com.xingda.packing.dmss.minitor.service.IPkAlarmHistoryService;
import com.xingda.packing.dmss.plc.service.PlcDirectiveService;
import com.xingda.packing.dmss.service.TaskManagerService3;
import com.xingda.packing.dmss.shunt.ticket.ShuntTicket;
import com.xingda.packing.dmss.task.ticket.AbstractTaskTicket;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;

@Component
@Slf4j
public class ShuntProductionLine {
    @Resource
    @Getter
    IPkAlarmHistoryService pkAlarmHistoryService;
    @Resource
    @Getter
    EventCreater eventCreater;
    @Resource
    @Getter
    private ShuntArea shuntArea;
    @Resource
    private StorageUtils storageUtils;
    @Resource
    private TaskManagerService3 taskManagerService3;
    @Getter
    @Setter
    private boolean initRunning = false;
    @Setter
    @Getter
    private AbstractTaskTicket taskTicket;
    @Resource
    private PlcDirectiveService plcDirectiveService;
    @Resource
    @Getter
    private PackProductionLine packProductionLine;
    @Resource
    private PkVisualSenseMapper pkVisualSenseMapper;
    @Getter
    @Setter
    private int codeErrorNum = 0;
    @Getter
    @Setter
    private int snapErrorNum = 0;

    /**
     * 初始化
     */
    public void initStatus() {
        AbstractTaskTicket ticket = storageUtils.loadTaskTicket(3);
        this.setTaskTicket(ticket);
    }

    /**
     * 开启
     */
    public void start() {
        CompletableFuture.runAsync(taskManagerService3);
    }

    /**
     * 是否可以下发任务
     */
    public boolean checkCanAssignTaskTicket() {
        return taskTicket == null || taskTicket.getState() == TaskState.FINISH;
    }

    public void assignTaskTicket(AbstractTaskTicket taskTicket) {
        if (checkCanAssignTaskTicket()) {
            this.taskTicket = taskTicket;
            log.info("分流区任务单下发成功：任务单类型：{}", taskTicket.getType().getTypeName());
        }
    }

    public boolean isScanSignal() {
        return plcDirectiveService.isShuntAreaSignal();
    }

    public boolean isSnapSignal() {
        return plcDirectiveService.isSnapSignal();
    }

    /**
     * 获得分流区条形码
     */
    public String getScanWheelNo() {
        return plcDirectiveService.getShuntAreaScanWheelNo();
    }

    public void wheelToLeftOrRight(int area, String code) {
        plcDirectiveService.writeValueToShuntArea(area, code);
    }

    public boolean isShuntOver() {
        return plcDirectiveService.isShuntOver();
    }

    public void restartShuntAreaSignal() {
        plcDirectiveService.restartShuntAreaSignal();
    }

    public List<ProductBoxLocation> getAllProductBoxLocation() {
        List<ProductBoxLocation> list = new ArrayList<>();
        List<ProductBoxLocation> locationList1 = packProductionLine.getProductArea().locationList1;
        List<ProductBoxLocation> locationList2 = packProductionLine.getProductArea().locationList2;
        list.addAll(locationList1);
        list.addAll(locationList2);
        return list;
    }

    public boolean repeatPacking(String barCode) {
        return packProductionLine.getProductArea().isAlreadyPacking(barCode);
    }

    public boolean isBothFull() {
        return !shuntArea.canPutToSql(1) && !shuntArea.canPutToSql(2);
    }

    public boolean canShut(int location) {
        if (location == 1) {
            return shuntArea.canPutToSql(1);
        } else {
            return shuntArea.canPutToSql(2);
        }
    }

    public void handleShuntEvent(ShuntTicket shuntTicket) {
        this.codeErrorNum = 0;
        this.snapErrorNum = 0;
        eventCreater.createTriggerAlarm(AlarmTriggerType.SHUNT_AREA_CODE_ERROR_MORE_THAN_THREE, false, 3);
        eventCreater.createTriggerAlarm(AlarmTriggerType.SHUNT_AREA_SNAP_ERROR_MORE_THAN_THREE, false, 3);
        eventCreater.createTriggerAlarm(AlarmTriggerType.PRODUCT_TYPE_ERROR, false, 3);
        eventCreater.createTriggerAlarm(AlarmTriggerType.NO_PRODUCT_TYPE, false, 3);
        eventCreater.createTriggerAlarm(AlarmTriggerType.SHUNT_AREA_WHEEL_NO_AVAILABLE, false, 3);
        eventCreater.createTriggerAlarm(AlarmTriggerType.SHUNT_AREA_WHEEL_NO_SHUNT, false, 3);
        eventCreater.createTriggerAlarm(AlarmTriggerType.WHEEL_ALREADY_PACKING, false, 3);
        eventCreater.createTriggerAlarm(AlarmTriggerType.WHEEL_ERROR_99, false, 3);
        eventCreater.createTriggerAlarm(AlarmTriggerType.WHEEL_ERROR_999, false, 3);
        eventCreater.createTriggerAlarm(AlarmTriggerType.WHEEL_ERROR_9999, false, 3);
        eventCreater.createPkEvent(EventType.SHUNT, 3, "分流区颜色:" + WheelSurfaceType.getByAB(shuntTicket.getWheel().getAb()).getGr());
        eventCreater.createPkEvent(EventType.SHUNT, 3, WorkAreaType.getByID(3).getTypeName() + ":读码完成:", shuntTicket.getWheel().getBarCode(), "，<br>扭转值：", shuntTicket.getWheel().getTorsionValue().setScale(2, RoundingMode.HALF_UP).doubleValue(), "，<br>焊点数：", shuntTicket.getWheel().getSolderJointCount(), "，<br>是否重卷：", shuntTicket.getWheel().isAnew(), "，<br>产品类别：", shuntTicket.getWheel().getVFree2(), "，<br>客户：", shuntTicket.getWheel().getConsumerName());
        eventCreater.createPkEvent(EventType.SHUNT, 3, WorkAreaType.getByID(3).getTypeName() + ":分流方向:" + ShuntAreaType.getByLocation(shuntTicket.getLocation()).getTypeName());
        storageUtils.saveTaskTicket(taskTicket, 3);
        packProductionLine.getRobot().setTagValue(3, false);
    }

    public int getProductType() {
        return plcDirectiveService.getProductTypeToShunt();
    }

    public void createNoProductTypeEvent() {
        eventCreater.createTriggerAlarm(AlarmTriggerType.NO_PRODUCT_TYPE, true, 3);
        eventCreater.createPkEvent(EventType.SHUNT, 3, WorkAreaType.getByID(3).getTypeName() + ":<br>从PLC未读取到工字轮类型,已停止分流区任务");
        stopTask();
    }

    public void saveTicket(ShuntTicket shuntTicket) {
        this.taskTicket = shuntTicket;
        storageUtils.saveTaskTicket(shuntTicket, 3);
    }


    public void createAlarmEvent(String content) {
        eventCreater.createPkEvent(EventType.SHUNT, 3, WorkAreaType.getByID(3).getTypeName() + ":" + content);
    }

    public void createShuntEvent(ShuntTicket shuntTicket) {
        storageUtils.saveTaskTicket(shuntTicket, 3);
        eventCreater.createPkEvent(EventType.SHUNT, 3, WorkAreaType.getByID(3).getTypeName() + ":<br>创建任务成功,工字轮高度:" + WheelHeight.getByID(shuntTicket.getProductType()).getTypeName());
    }

    public void listenerShuntEvent(ShuntTicket taskTicket) {
        storageUtils.saveTaskTicket(taskTicket, 3);
        eventCreater.createPkEvent(EventType.SHUNT, 3, WorkAreaType.getByID(3).getTypeName() + ":<br>分流完成,分流方向:", ShuntAreaType.getByLocation(taskTicket.getLocation()).getTypeName());
    }

    public void saveVisualSense(String scanWheelNo, int area) {
        PkVisualSense pkVisualSense = new PkVisualSense();
        pkVisualSense.setArea(area);
        if (scanWheelNo == null) {
            scanWheelNo = "#";
        }
        pkVisualSense.setScanWheelNo(scanWheelNo);
        pkVisualSense.setCreateTime(new Date());
        pkVisualSenseMapper.insert(pkVisualSense);
    }


    public void codeParsingSucceeded() {
        plcDirectiveService.codeParsingSucceeded();
    }

    public void codeParsingFailed() {
        plcDirectiveService.codeParsingFailed();
    }

    public void snapParsingSucceeded() {
        plcDirectiveService.snapParsingSucceeded();
    }

    public void snapParsingFailed() {
        plcDirectiveService.snapParsingFailed();
    }

    public void stopTask() {
        ShuntTicket shuntTicket = new ShuntTicket();
        shuntTicket.setState(TaskState.FINISH);
        setTaskTicket(shuntTicket);
        saveTicket(shuntTicket);
        setInitRunning(false);
    }
}
